home *** CD-ROM | disk | FTP | other *** search
/ Trading on the Edge / Trading On The Edge - CD-ROM Toolkit (Wayzata Technology)(2031)(1994).bin / pc / mac_file / software / nn_prepr / finevl.c < prev    next >
C/C++ Source or Header  |  1992-08-25  |  12KB  |  363 lines

  1. /* 17:53 23-Aug-92  (finevl.c)  Evaluation Function */
  2.  
  3. #include "fin.h"
  4.  
  5. /************************************************************************
  6.  * Copyright(C) 1992 High-Tech Communications.                          *
  7.  * 103 Buckskin Court, Sewickley, PA 15143                              *
  8.  *                                                                      *
  9.  * Written by Casimir C. Klimasauskas                                   *
  10.  *                                                                      *
  11.  * All rights reserved.  No part of this program may be reproduced,     *
  12.  * stored in a retrieval system, or tramsmitted, in any form or by any  *
  13.  * means, electronic, mechanical, photocopying, recording or otherwise  *
  14.  * without the prior written permission of the copyright owner,         *
  15.  * High-Tech Communications.                                            *
  16.  *                                                                      *
  17.  * These programs are supplied on an "as-is" basis with no warranties   *
  18.  * of fitness or operability, either express or implied.                *
  19.  *                                                                      *
  20.  ************************************************************************
  21.  */
  22.  
  23. double StdDevD( vFP, nI )    /* compute variance */
  24. float    *vFP;        /* vector to work on */
  25. int     nI;        /* # of items in vector */
  26. {
  27.     double     SumXD;        /* sum of values */
  28.     double     SumXXD;    /* sum of squared values */
  29.     double     vD;        /* work value */
  30.     float    *pF;        /* work pointer */
  31.     int         I;        /* work index */
  32.  
  33.     if ( nI <= 1 ) return( 0.0 );
  34.  
  35.     for( SumXD=0.0, I=nI, pF=vFP; --I >= 0; pF++ )
  36.     SumXD += (*pF);
  37.     SumXD /= nI;        /* average */
  38.  
  39.     for( SumXXD=0., I=nI, pF=vFP; --I >= 0; pF++ ) {
  40.     vD = *pF - SumXD;
  41.     SumXXD += vD * vD;
  42.     }
  43.     vD = sqrt( SumXXD / (nI - 1) );
  44.  
  45.     return( vD );
  46. }
  47.  
  48.  
  49. NetEvalV( NSigFP, PriceFP, DateLP,
  50.       wBSSigIP, wEqFP, wPLFP,
  51.       VecI, OptsI, prtFP,
  52.       srtLD, srtHD, buyLD, buyHD, CapitalD )
  53. float        *NSigFP;    /* (i) neural net signal */
  54. float        *PriceFP;    /* (i) price */
  55. long        *DateLP;    /* (i) date */
  56. int        *wBSSigIP;    /* (w) buy-sell signal */
  57. float        *wEqFP;        /* (w) equity */
  58. float        *wPLFP;        /* (w) P&L */
  59. int         VecI;        /* (i) # of vector items */
  60. int         OptsI;        /* (i) =1, print detail; =0, summary */
  61. FILE        *prtFP;        /* (i) file pointer for printer output */
  62. double         srtLD;        /* (i) low limit for srt sales */
  63. double         srtHD;        /* (i) high limit for srt sales */
  64. double         buyLD;        /* (i) low limit for long */
  65. double         buyHD;        /* (i) high limit for long */
  66. double         CapitalD;    /* (i) initial capital */
  67. {
  68.     int         rI;        /* row index */
  69.     int         trsI;        /* transformed signal */
  70.     int         bsI;        /* buy-sell signal index */
  71.     int         positionI;    /* position -1=short; 0=out; 1=long */
  72.     int         CurSigI;    /* current signal */
  73.     int         PrvSigI;    /* previous signal */
  74.     double     EquityD;    /* equity */
  75.     double     CurPriceD;    /* current price */
  76.     double     PrvPriceD;    /* previous price */
  77.     double     vD;        /* work double */
  78.  
  79.     double     TransSizeD = 1000.;    /* transaction size */
  80.     double     TransCostD = 100.;    /* transaction costs */
  81.  
  82.     double     GainD;        /* gain on a trade */
  83.     double     LossD;        /* loss on a trade */
  84.     double     DrawDnD;    /* draw down */
  85.  
  86.     int         TotTradesI;    /* total number of trades */
  87.     int         ProfTradesI;    /* profitable trades */
  88.     int         runsI;        /* # of runs? */
  89.     int         nDrawDnI;    /* # of draw downs */
  90.     int         MaxDrawDnI;    /* max # of drawdowns */
  91.     double     MaxGainD;    /* maximum gain */
  92.     double     MaxLossD;    /* maximum loss */
  93.     double     MaxDrawDnD;    /* maximum draw-down */
  94.     double     TotGainD;    /* total gains */
  95.     double     TotLossD;    /* total losses */
  96.  
  97.     int         numberofdaysI;    /* # of days in time */
  98.     int         wI;        /* work int */
  99.     double     SDevD;        /* standard deviation */
  100.     double     AvgPLD;    /* average P&L */
  101.     double     vX, vY, vK;    /* work values */
  102.     double     ZScoreD;    /* Z-Score */
  103.  
  104. /* --- convert an analog signal to a short(-1)-neutral(0)-long(1) signal --- */
  105. #define SIG(v) \
  106.     (srtLD<=(v)&&(v)<=srtHD?SHORT:((buyLD<=(v)&&(v)<=buyHD)?LONG:FLAT))
  107.  
  108. #define    LONG    (1)
  109. #define    FLAT    (0)
  110. #define    SHORT    (-1)
  111.  
  112. #define    BUY    LONG
  113. #define    HOLD    FLAT
  114. #define    SELL    SHORT
  115. #define    TRADING_DAYS    250.
  116.  
  117.     if ( srtLD > srtHD ) { vD = srtLD; srtLD = srtHD; srtHD = vD; }
  118.     if ( buyLD > buyHD ) { vD = buyLD; buyLD = buyHD; buyHD = vD; }
  119.     if ( srtHD > buyLD ) { vD = (srtHD+buyLD)*.5; srtHD = buyLD = vD; }
  120.  
  121.     /* --- initialize accumulators --- */
  122.  
  123.     TotTradesI = 0;
  124.     ProfTradesI = 0;
  125.     runsI = 0;
  126.     nDrawDnI = 0;
  127.     MaxDrawDnI = 0;
  128.     MaxGainD = 0.0;
  129.     MaxLossD = 0.0;
  130.     MaxDrawDnD = 0.0;
  131.     TotGainD = 0.0;
  132.     TotLossD = 0.0;
  133.  
  134.     /* --- Figure out buy-hold-sell signals --- */
  135.  
  136.     for( rI = 0; rI < VecI; rI++ ) {
  137.  
  138.     /* part 2: calculate the buy/sell signal */
  139.  
  140.     trsI = SIG(NSigFP[rI]);        /* generate short-neutral-long */
  141.     if ( rI == 0 ) {
  142.         bsI = positionI = trsI;    /* initial values */
  143.     } else {
  144.         switch( positionI ) {
  145.         case LONG:        /* current position long */
  146.         switch( trsI ) {
  147.         case LONG:    bsI = BUY;  positionI = LONG;    break;
  148.         case FLAT:
  149.         case SHORT:    bsI = SELL; positionI = FLAT;    break;
  150.         }
  151.         break;
  152.  
  153.         case FLAT:        /* current position flat */
  154.         switch( trsI ) {
  155.         case LONG:    bsI = BUY;  positionI = LONG;    break;
  156.         case FLAT:    bsI = HOLD; positionI = FLAT;    break;
  157.         case SHORT:    bsI = SELL; positionI = SHORT;    break;
  158.         }
  159.         break;
  160.  
  161.         case SHORT:        /* current position short */
  162.         switch( trsI ) {
  163.         case LONG:
  164.         case FLAT:    bsI = BUY;  positionI = FLAT;    break;
  165.         case SHORT:    bsI = SELL; positionI = SHORT;    break;
  166.         }
  167.         break;
  168.         }
  169.     }
  170.     wBSSigIP[rI] = bsI;
  171.     }
  172.  
  173.     /* --- Compute P&L --- */
  174.  
  175.     EquityD = CapitalD;            /* initial capital */
  176.     PrvPriceD = 0.0;            /* nothing yet */
  177.     PrvSigI = wBSSigIP[0];        /* initial signal */
  178.     for( rI = 0; rI < VecI; rI++ ) {
  179.  
  180.     /* part 3: calculate the P&L and equity from each trade */
  181.  
  182.     CurSigI   = wBSSigIP[rI];    /* current signal */
  183.     CurPriceD = PriceFP[rI];    /* current price */
  184.     wPLFP[rI] = 0.0;        /* initialize P&L */
  185.     wEqFP[rI] = EquityD;        /* initialize Equity (no trade) */
  186.     if ( rI == 0 ) {
  187.         /* --- first row of data --- */
  188.         if ( CurSigI != HOLD ) {
  189.         PrvPriceD = CurPriceD;
  190.         PrvSigI   = CurSigI;
  191.         }
  192.         continue;
  193.     }
  194.  
  195.     /* --- subsequent rows of data --- */
  196.  
  197.     if ( CurSigI == HOLD && PrvSigI == HOLD )
  198.         continue;        /* no change */
  199.     if ( (CurSigI == BUY  && PrvSigI == HOLD) ||
  200.          (CurSigI == SELL && PrvSigI == HOLD) ) {
  201.         PrvPriceD = CurPriceD;
  202.         PrvSigI   = CurSigI;
  203.         continue;        /* bought or sold from neutral */
  204.     }
  205.     if ( CurSigI == HOLD && PrvSigI != HOLD )
  206.         /* --- when just completing a trade and going FLAT --- */
  207.         continue;        /* keep current position */
  208.  
  209.     /* part 4: calculate GAIN & LOSSES for each trade */
  210.     /*    In this section, trades are completed. */
  211.  
  212.     if ( CurSigI == SELL && PrvSigI == BUY ) {
  213.         /* 1. switching from a LONG to SHORT position */
  214.         if ( CurPriceD >= PrvPriceD ) {
  215.         /* 1.0 switch resulted in a profit */
  216.         GainD = ((CurPriceD - PrvPriceD) * TransSizeD) - TransCostD;
  217.         GainTrade:
  218.         TotTradesI++;
  219.         ProfTradesI++;
  220.         runsI++;
  221.         if ( GainD > MaxGainD ) MaxGainD = GainD;
  222.         TotGainD += GainD;
  223.         EquityD += GainD;
  224.         wEqFP[rI] = EquityD;
  225.         wPLFP[rI] = GainD;
  226.  
  227.         PrvSigI = 0;
  228.         DrawDnD = 0.0;
  229.         nDrawDnI = 0;
  230.         continue;
  231.         } else {
  232.         /* 1.1 switch resulted in a loss */
  233.         LossD = ((PrvPriceD - CurPriceD)*TransSizeD) - TransCostD;
  234.         LossTrade:
  235.         TotTradesI++;
  236.         runsI++;
  237.         if ( LossD > MaxLossD ) MaxLossD = LossD;
  238.         TotLossD += LossD;
  239.         EquityD  -= LossD;
  240.  
  241.         wEqFP[rI] = EquityD;
  242.         wPLFP[rI] = -LossD;
  243.  
  244.         /* --- Calculate Draw-down & Max Draw-down --- */
  245.  
  246.         DrawDnD += LossD;
  247.         nDrawDnI++;
  248.         if ( nDrawDnI > MaxDrawDnI ) MaxDrawDnI = nDrawDnI;
  249.         if ( DrawDnD  > MaxDrawDnD ) MaxDrawDnD = DrawDnD;
  250.  
  251.         PrvSigI = HOLD;
  252.         continue;
  253.         }
  254.     }
  255.  
  256.     if ( CurSigI == BUY && PrvSigI == SELL ) {
  257.         /* 2. Switching from a SHORT to LONG trade */
  258.         if ( CurPriceD <= PrvPriceD ) {
  259.         /* 2.0 Switch resulted in a PROFIT */
  260.         GainD = ((PrvPriceD - CurPriceD) * TransSizeD)-TransCostD;
  261.         goto GainTrade;
  262.         } else {
  263.         /* 2.1 Switch resulted in a LOSS */
  264.         LossD  = ((CurPriceD - PrvPriceD) * TransSizeD)-TransCostD;
  265.         goto LossTrade;
  266.         }
  267.     }
  268.     }
  269.  
  270.     /* Part 5: report output results on NN Predicted Values */
  271.  
  272.     numberofdaysI = (VecI * 365.) / TRADING_DAYS;
  273.     fprintf( prtFP, "%-40s %10.2f\n",
  274.     "Period (years)", numberofdaysI/365.+0.005 );
  275.     fprintf( prtFP, "%-40s %7d\n",
  276.     "Number of Trades", TotTradesI );
  277.     fprintf( prtFP, "%-40s %7d\n",
  278.     "Profitable Trades", ProfTradesI );
  279.     fprintf( prtFP, "%-40s %10.2f %%\n",
  280.     "Profitable Trades",
  281.     TotTradesI? (100.*((double)ProfTradesI)/TotTradesI):0.0 );
  282.     fprintf( prtFP, "%-40s %10.2f\n",
  283.     "Average Trades per Year",
  284.     ((double)TotTradesI)/((double)numberofdaysI) * 365. );
  285.     fprintf( prtFP, "%-40s %10.2f\n",
  286.     "Average Gain per Profitable Trade",
  287.     ProfTradesI? (TotGainD/ProfTradesI):0.0 );
  288.  
  289.     wI = TotTradesI - ProfTradesI;
  290.     fprintf( prtFP, "%-40s %10.2f\n",
  291.     "Average Loss per Losing Trade",
  292.     wI? (TotLossD/wI):0.0 );
  293.  
  294.     AvgPLD = TotTradesI? ((TotGainD - TotLossD)/TotTradesI):0.;
  295.     fprintf( prtFP, "%-40s %10.2f\n",
  296.     "Average P&L per Trade", AvgPLD );
  297.     SDevD = StdDevD( wPLFP, VecI );
  298.     fprintf( prtFP, "%-40s %10.2f\n",
  299.     "Standard Deviation of P&L", SDevD );
  300.     fprintf( prtFP, "%-40s %10.2f\n",
  301.     "Total P&L Over the Period", TotGainD - TotLossD );
  302.  
  303.     wI = TotTradesI - ProfTradesI;
  304.     fprintf( prtFP, "%-40s %10.2f\n",
  305.     "Ratio of Profitable / Losing Trades",
  306.     wI? (((double)ProfTradesI)/wI):0. );
  307.     fprintf( prtFP, "%-40s %10.2f\n",
  308.     "Net Equity at End of Period", EquityD );
  309.     fprintf( prtFP, "%-40s %10.2f\n",
  310.     "Maximum Gain per Single Trade", MaxGainD );
  311.     fprintf( prtFP, "%-40s %10.2f\n",
  312.     "Maximum Loss per Single Trade", -MaxLossD );
  313.     fprintf( prtFP, "%-40s %10.2f\n",
  314.     "Maximum Draw Down", -MaxDrawDnD );
  315.  
  316.     vD = EquityD < 0.? 0.:(pow(EquityD/CapitalD, 1./numberofdaysI) - 1.);
  317.     fprintf( prtFP, "%-40s %10.2f %%\n",
  318.     "Total Rate of Return (Daily)", vD * 100. );
  319.  
  320.     vD = EquityD < 0.? 0.:(pow(EquityD/CapitalD, 1./(numberofdaysI/365.)) - 1.);
  321.     fprintf( prtFP, "%-40s %10.2f %%\n",
  322.     "Total Rate of Return (Annualized)", vD * 100. );
  323.  
  324.     fprintf( prtFP, "%-40s %11.3f\n",
  325.     "Sharp Ratio", SDevD? (AvgPLD/SDevD):0. );
  326.  
  327.     ZScoreD = SDevD? ((AvgPLD/SDevD)*sqrt((double)TotTradesI)):0.;
  328.     fprintf( prtFP, "%-40s %11.3f\n", "Z-Score", ZScoreD );
  329.  
  330.     vX = 1.0 / ((fabs(ZScoreD) * 0.2316419) + 1.0);
  331.     vY = vX * vX;
  332.     vK = ((vX * .31938153)-(vY*.356563782)+(vX*vY*1.781477937) -
  333.      (vY*vY*1.821255978) + (vY*vY*vX*1.330274429));
  334.     vD = 1. - (2. * vK * (1./sqrt(exp(ZScoreD*ZScoreD)*6.283185307)));
  335.     fprintf( prtFP, "%-40s %11.3f\n", "Confidence Limit", vD );
  336.  
  337.     fprintf( prtFP, "%-40s %10.2f\n",
  338.     "Average Profit per Year",
  339.     (TotGainD - TotLossD)/(numberofdaysI/365.) );
  340.  
  341.     if ( MaxDrawDnD == 0. ) vD = 0.;
  342.     else vD = ((TotGainD - TotLossD)/(numberofdaysI/365.)) / MaxDrawDnD;
  343.     fprintf( prtFP, "%-40s %10.2f\n",
  344.     "Average Profit / Max Draw Down", vD );
  345.  
  346.     vD = (PriceFP[VecI-1] - PriceFP[0]) / PriceFP[0];
  347.     fprintf( prtFP, "%-40s %10.2f %%\n", "Buy & Hold", vD*100. );
  348.  
  349.     if ( OptsI ) {
  350.     /* --- Print out details --- */
  351.     fprintf( prtFP,
  352. "\n      Date     Price    Signal       B/S       P&L    Equity\n\n" );
  353.     for( rI = 0; rI < VecI; rI++ )
  354.         fprintf( prtFP, "%10s%10.2f%10.2f%10d%10.2f%10.2f\n",
  355.         Date2StrCP( DateLP[rI] ),
  356.         PriceFP[rI], NSigFP[rI], wBSSigIP[rI], wPLFP[rI], wEqFP[rI] );
  357.     fprintf( prtFP, "\n" );
  358.     }
  359.  
  360.     fflush( prtFP );
  361.     return( 0 );
  362. }
  363.